﻿/* Write a program that reads a rectangular matrix of size N x M and finds in it the square 3 x 3 
 * that has maximal sum of its elements. */

using System;

class MaxSumNM
{
    static void Main()
    {
        //get matrix size from user input
        uint N, M;

        //check for invalid input
        bool iProvided = false;
        do
        {
            if (iProvided == true) Console.WriteLine("Error: invalid input! Please enter a positive integer. Please note the matrix size must be at least 3x3\r\n\t* Valid input: N >= 3");
            else iProvided = true;
            Console.Write("Enter N: ");
        } while (UInt32.TryParse(Console.ReadLine(), out N) == false || N < 3);
        
        iProvided = false; //reset iProvided
        do
        {
            if (iProvided == true) Console.WriteLine("Error: invalid input! Please enter a positive integer. Please note the matrix size must be at least 3x3\r\n\t* Valid input: M >=3 0");
            else iProvided = true;
            Console.Write("Enter M: ");
        } while (UInt32.TryParse(Console.ReadLine(), out M) == false || M < 3);

        Console.WriteLine(N + " x " + M);

        int[,] matrix = new int[N,M];
        int input;
        //fill the matrix
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < M; j++)
            {
                iProvided = false; //reset iProvided
                do
                {
                    if (iProvided == true) Console.WriteLine("Error: invalid input! Please enter a positive integer.\r\n\t* Valid input: M > 0");
                    else iProvided = true;
                    Console.Write("Enter Element {0}, {1}: ", i, j);
                } while (Int32.TryParse(Console.ReadLine(), out input) == false);
                matrix[i, j] = input;

            }
        }
        PrintMatrix(matrix);

        int[] sums = new int[N*M+1];
        string[] offsets = new string[N*M+1];
        int sumCounter = 0;

        for (int i = 0; i < matrix.GetLength(0)-2; i++)
        {
            for (int j = 0; j < matrix.GetLength(1)-2; j++)
            {
                sums[sumCounter] = SqSum(matrix, i, j);
                //Console.WriteLine(sums[sumCounter]);
                offsets[sumCounter] = i + "," + j;
                //Console.WriteLine(offsets[sumCounter]);
                sumCounter++;
            }
        }
        
        //get the maximum square index
        int max = 0, maxI = 0;
        for (int i = 0; i < sums.Length; i++)
        {
            if (sums[i] > max)
            {
                max = sums[i];
                maxI = i;
            }
        }
        Console.WriteLine("Maximum square sum: {0} {1}", sums[maxI], max);
        Console.WriteLine("Maximum square starting indices: " + offsets[maxI]);
        
        string[] coords = offsets[maxI].Split(',');
        int maxStartRow = Convert.ToInt32(coords[0]);
        int maxStartCol = Convert.ToInt32(coords[1]);

        Console.WriteLine("Coordinates: \r\n\tStarting row: {0}\r\n\tStarting column: {1}", maxStartRow, maxStartCol);
        //Console.WriteLine(maxStartRow);
        //Console.WriteLine(maxStartCol);
        Console.WriteLine("Matrix with the biggest sum: ");
        PrintMatrix(matrix, maxStartRow, maxStartCol, maxStartRow+3, maxStartCol+3);
       
    }

    //calculate the square sum by getting the starting point (row, column) as a parameter
    private static int SqSum(int[,] matrix, int startRow, int startCol)
    {
        int endRow = startRow + 3;
        int endCol = startCol + 3;

        string nums = "";
        int i = 0, sum = 0;
        for (int row = startRow; row < endRow; row++)
        {
            for (int col = startCol; col < endCol; col++)
            {
                sum += matrix[row, col];
                nums += matrix[row, col] + " ";
            }
        }
        //Console.WriteLine(nums);
        return sum;
    }

    private static void PrintMatrix(int[,] matrix, int StartRow, int StartCol, int EndRow, int EndCol)
    {
        for (int row = StartRow; row < EndRow; row++)
        {

            for (int col = StartCol; col < EndCol; col++) Console.Write("{0,-5}", matrix[row, col]);
            Console.WriteLine();
        }
        Console.WriteLine();
    }


    private static void PrintMatrix(int[,] matrix, int startRow = 0, int startCol = 0)
    {
        for (int row = 0; row < matrix.GetLength(0); row++)
        {

            for (int col = 0; col < matrix.GetLength(1); col++) Console.Write("{0,-5}", matrix[row, col]);
            Console.WriteLine();
        }
        Console.WriteLine();
    }

}
